﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cosmos.Core;

namespace SharkOS.Core.Souris
{
    class Souris
    {
        public Cosmos.Hardware.Mouse souris = new Cosmos.Hardware.Mouse();
        public uint x;
        public uint y;
        public uint oc = 0;
        public void initialiser()
        {
            Initialize();
            uint mx = (uint)getX();
            uint my = (uint)getY();
            x = mx;
            y = my;
        }
        public int getX()
        {
            return souris.X;
        }
        public int getY()
        {
            return souris.Y;
        }
        public Boolean SiCliqueGauche()
        {
            if (souris.Buttons == Cosmos.Hardware.Mouse.MouseState.Left)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public Boolean SiCliqueDroit()
        {
            if (souris.Buttons == Cosmos.Hardware.Mouse.MouseState.Right)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public Boolean SiCliqueMilieu()
        {
            if (souris.Buttons == Cosmos.Hardware.Mouse.MouseState.Middle)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public Boolean SiCliqueRien()
        {
            if (souris.Buttons == Cosmos.Hardware.Mouse.MouseState.None)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public void Initialize()
        {
            ////enable mouse
            WaitSignal();
            BaseIOGroups.Mouse.p64.Byte = (byte)0xA8;

            //// enable interrupt
            WaitSignal();
            BaseIOGroups.Mouse.p64.Byte = (byte)0x20;
            WaitData();
            //byte status1 = (byte)(BaseIOGroups.Mouse.p60.Byte);
            byte status = (byte)(BaseIOGroups.Mouse.p60.Byte | 2);
            WaitSignal();
            BaseIOGroups.Mouse.p64.Byte = (byte)0x60;
            WaitSignal();
            BaseIOGroups.Mouse.p60.Byte = (byte)status;

            ////default 
            Write(0xF6);
            Read();  //Acknowledge

            ////Enable the mouse
            Write(0xF4);
            Read();  //Acknowledge

            //Set the IRQ 12, to the method HandleMouse
            INTs.SetIrqHandler(12, HandleMouse);
        }

        private byte Read()
        {
            WaitData();
            return BaseIOGroups.Mouse.p60.Byte;
        }

        private void Write(byte b)
        {
            WaitSignal();
            BaseIOGroups.Mouse.p64.Byte = 0xD4;
            WaitSignal();
            BaseIOGroups.Mouse.p60.Byte = b;
        }

        private void WaitData()
        {
            for (int i = 0; i < 100 & ((BaseIOGroups.Mouse.p64.Byte & 1) == 1); i++)
                ;
        }
        public int X;
        /// <summary>
        /// The Y location of the mouse.
        /// </summary>
        public int Y;
        private void WaitSignal()
        {
            for (int i = 0; i < 100 & ((BaseIOGroups.Mouse.p64.Byte & 2) != 0); i++)
                ;
        }
        private byte[] mouse_byte = new byte[4];
        private byte mouse_cycle = 0;
        public MouseState Buttons;
        public enum MouseState
        {
            /// <summary>
            /// No button is pressed.
            /// </summary>
            None = 0,
            /// <summary>
            /// The left mouse button is pressed.
            /// </summary>
            Left = 1,
            /// <summary>
            /// The right mouse button is pressed.
            /// </summary>
            Right = 2,
            /// <summary>
            /// The middle mouse button is pressed.
            /// </summary>
            Middle = 4
        }
        public void HandleMouse(ref INTs.IRQContext context)
        {
            switch (mouse_cycle)
            {
                case 0:
                    mouse_byte[0] = Read();

                    //Bit 3 of byte 0 is 1, then we have a good package
                    if ((mouse_byte[0] & 0x8) == 0x8)
                        mouse_cycle++;

                    break;
                case 1:
                    mouse_byte[1] = Read();
                    mouse_cycle++;
                    break;
                case 2:
                    mouse_byte[2] = Read();
                    mouse_cycle = 0;

                    if ((mouse_byte[0] & 0x10) == 0x10)
                        X -= (mouse_byte[1] ^ 0xff);
                    else
                        X += mouse_byte[1];

                    if ((mouse_byte[0] & 0x20) == 0x20)
                        Y += (mouse_byte[2] ^ 0xff);
                    else
                        Y -= mouse_byte[2];

                    if (Y < 0)
                        Y = 0;
                    if (X < 0)
                        X = 0;

                    Buttons = (MouseState)(mouse_byte[0] & 0x7);

                    break;
            }
        }
    }
}
